package com.cgrs572.shortlink.project.mq.producer;

import cn.hutool.core.lang.UUID;
import com.cgrs572.shortlink.project.dto.biz.ShortLinkStatsRecordDTO;
import lombok.RequiredArgsConstructor;
import org.redisson.api.RBlockingDeque;
import org.redisson.api.RDelayedQueue;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Component;
import java.util.concurrent.TimeUnit;

import static com.cgrs572.shortlink.project.common.constant.RedisKeyConstant.DELAY_QUEUE_STATS_KEY;

/**
 * 延迟消费短链接统计发送者
 * 功能：通过 Redisson 的 延迟队列（Delayed Queue） ，实现 延时任务处理机制
 */
@Component
@RequiredArgsConstructor
public class DelayShortLinkStatsProducer {

    private final RedissonClient redissonClient;

    /**
     * 发送延迟消费短链接统计
     * @param statsRecord 短链接统计实体参数
     */
    public void send(ShortLinkStatsRecordDTO statsRecord) {
        // 设置延迟队列中消息的幂等标识
        statsRecord.setKeys(UUID.fastUUID().toString());
        // 从 Redisson 获取一个阻塞双端队列RBlockingDeque,存储的数据为统计短链接信息的对象---队列为空时，消费者线程会被阻塞直到队列有新元素可以消费，支持从队列的两端（头部和尾部）插入和移除元素;
            // 参数为短链接延迟队列消费统计 Key
        RBlockingDeque<ShortLinkStatsRecordDTO> blockingDeque = redissonClient.getBlockingDeque(DELAY_QUEUE_STATS_KEY);
        // 通过redissonClient(Redis客户端)接口的getDelayedQueue()方法将获取的 blockingDeque 队列包装成一个 延迟队列（RDelayedQueue）
            // 延迟队列（RDelayedQueue）允许将元素放入队列，并指定一个延迟时间，元素在延迟时间到期之前是无法被消费的
        RDelayedQueue<ShortLinkStatsRecordDTO> delayedQueue = redissonClient.getDelayedQueue(blockingDeque);
        // 将 统计短链接信息的对象放入到 延迟队列（RDelayedQueue）中并设置延迟时间
            // statsRecord 会在队列中等待 5 秒钟后才能被消费
        delayedQueue.offer(statsRecord, 5, TimeUnit.SECONDS);
    }
}
